package com.module.ble.db

import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.common.base.utils.AppUtils
import com.module.ble.db.table.UserBloodOxygen
import com.module.ble.db.table.UserBodyTemperature
import com.module.ble.db.table.UserCalorie
import com.module.ble.db.table.UserEnvTemperature
import com.module.ble.db.table.UserHealthIntegratedData
import com.module.ble.db.table.UserHeartEntryTime
import com.module.ble.db.table.UserHeartRate
import com.module.ble.db.table.UserHrv
import com.module.ble.db.table.UserRespiratoryRate
import com.module.ble.db.table.UserSleepInfo
import com.module.ble.db.table.UserSportRecord
import com.module.ble.db.table.UserStand
import com.module.ble.db.table.UserStepNumber
import com.module.ble.db.table.UserStepsRelatedRecord
import com.module.ble.db.table.UserStress
import com.module.ble.db.table.UserAcLevel
import com.module.ble.repo.HealthIntegratedDataRepo

/**
 * 作者：sosou
 * <p>
 * 版本：1.0
 * <p>
 * 创建日期：2024/10/18
 * <p>
 * 描述：体检room数据库
 * <p>
 * 修订历史：
 */
@Database(
    entities = [UserHeartRate::class, UserBloodOxygen::class, UserBodyTemperature::class,
        UserEnvTemperature::class, UserStepNumber::class, UserSleepInfo::class, UserHeartEntryTime::class,
        UserSportRecord::class, UserHealthIntegratedData::class, UserStepsRelatedRecord::class, UserRespiratoryRate::class, UserStress::class, UserStand::class, UserHrv::class, UserCalorie::class, UserAcLevel::class],
    version = 3
)//添表升级
abstract class HealthExaAppDataBase : RoomDatabase() {

    companion object {
        var mChatDataBase: HealthExaAppDataBase? = null
        private var mCurrentUserId: String = ""

        fun getDb(userId: String): HealthExaAppDataBase? {
            // 第一次登录或切换用户，创建数据库实例
            // 如果先前有用户登录，则关闭之前用户的数据库实例
            if (mCurrentUserId != userId || mChatDataBase == null) {
                mCurrentUserId = userId
                mChatDataBase?.close()
                mChatDataBase = buildDatabase(userId)
            }
            return mChatDataBase
        }

        private fun buildDatabase(userId: String): HealthExaAppDataBase {
            return Room.databaseBuilder(AppUtils.getContext(), HealthExaAppDataBase::class.java, "br_health_examination_$userId.db")
                .allowMainThreadQueries()
                .setJournalMode(JournalMode.WRITE_AHEAD_LOGGING) // 启用WAL模式)
                .addMigrations(MIGRATION_1_2,MIGRATION_2_3)
                .build()
        }

        private val MIGRATION_1_2 = object : Migration(1, 2) {
            //运动数据表添加字段
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL("ALTER TABLE sport_record ADD COLUMN macAddress TEXT")
            }
        }

        private val MIGRATION_2_3 = object : Migration(2, 3) {// 添加新的Migration从版本2到版本3
            override fun migrate(database: SupportSQLiteDatabase) {
                // 更新所有表的timeZone字段为"Asia/Shanghai"
                database.execSQL("UPDATE heart_rate SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
                database.execSQL("UPDATE blood_oxygen SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
                database.execSQL("UPDATE body_temperature SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
                database.execSQL("UPDATE env_temperature SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
                database.execSQL("UPDATE step_number SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
                database.execSQL("UPDATE sleep_info SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
                database.execSQL("UPDATE heart_entry_time SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
                database.execSQL("UPDATE sport_record SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
                database.execSQL("UPDATE health_integrated_data SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
                database.execSQL("UPDATE steps_related_record SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
                database.execSQL("UPDATE respiratory_rate SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
                database.execSQL("UPDATE user_stress SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
                database.execSQL("UPDATE user_stand SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
                database.execSQL("UPDATE heart_rate_variability SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
                database.execSQL("UPDATE user_calorie SET timeZone = 'Asia/Shanghai' WHERE timeZone IS NULL OR timeZone != 'Asia/Shanghai'")
            }
        }
    }

    abstract fun getHeartRateDaoDao(): HeartRateDao
    abstract fun getHeartRateVariabilityDao(): HeartRateVariabilityDao
    abstract fun getBloodOxygenDao(): BloodOxygenDao
    abstract fun getBodyTemperatureDao(): BodyTemperatureDao
    abstract fun getEnvTemperatureDao(): EnvTemperatureDao
    abstract fun getStepNumberDao(): StepNumberDao
    abstract fun getSleepInfoDao(): SleepInfoDao
    abstract fun getHeartTimeEntryDao(): HeartEntryTimeDao
    abstract fun getSportRecordDao(): SportRecordDao
    abstract fun getHealthIntegratedDataDao(): HealthIntegratedDataDao
    abstract fun getStepsRelatedRecordDao(): UserStepsRelatedRecordDao
    abstract fun getRespiratoryRateDao(): RespiratoryRateDao
    abstract fun getUserStressDao(): UserStressDao
    abstract fun getUserStandDao(): UserStandDao
    abstract fun getUserCalorieDao(): UserCalorieDao
    abstract fun getUserAcLevelDao(): UserAcLevelDao

}
